﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Linq;
using System.Linq;
using System.Web;
using FacturIT.BLL.Model.Helper;
using FacturIT.BLL.Model.WorkingHour;

namespace FacturIT.Service.Repositories.WorkinhgHour
{
    public class WorkingHourRepository : IRepository<BLL.Model.WorkingHour.WorkingHour, int>
    {
        public WorkingHourRepository()
        {
            DB = new WorkingHourManagementDataContext(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["DatabaseToUse"]].ConnectionString);
        }

        protected Table<BLL.Model.WorkingHour.WorkingHour> DT
        {
            get { return ((WorkingHourManagementDataContext)base.DB).WorkingHours; }
        }

        public override BLL.Model.WorkingHour.WorkingHour Read(int id)
        {
            BLL.Model.WorkingHour.WorkingHour WorkingHour = ReadByID(id);
            return WorkingHour == null ? null : WorkingHour;
        }
        /*public BLL.Model.WorkingHour.WorkingHour Read(string name)
        {
            return (from WorkingHour in DT
                    where WorkingHour..ToLower().Equals(name.ToLower())
                    select WorkingHour).FirstOrDefault();
        }*/

        public override IEnumerable<BLL.Model.WorkingHour.WorkingHour> ReadAll()
        {
            return from WorkingHour in DT
                   orderby WorkingHour.StartTime
                   select WorkingHour;
        }

        public override IEnumerable<BLL.Model.WorkingHour.WorkingHour> ReadAll(params int[] ids)
        {
            return from WorkingHour in DT
                   where ids.Contains(WorkingHour.WorkingHourID)
                   select WorkingHour;
        }
        internal IEnumerable<BLL.Model.WorkingHour.WorkingHour> ReadAll(List<int> assetIDs)
        {
            return from WorkingHour in DT
                   where assetIDs.Contains(WorkingHour.WorkingHourID)
                   select WorkingHour;
        }
        

        public override BLL.Model.WorkingHour.WorkingHour Add(BLL.Model.WorkingHour.WorkingHour t)
        {
            DT.InsertOnSubmit(t);
            SaveChanges();
            return ReadByID(t.WorkingHourID);
        }

        public override bool Delete(BLL.Model.WorkingHour.WorkingHour t)
        {
            DT.DeleteOnSubmit(t);
            SaveChanges();
            return !Exists(t.WorkingHourID);
        }

        public override BLL.Model.WorkingHour.WorkingHour Update(BLL.Model.WorkingHour.WorkingHour t)
        {
            UpdateObject(ReadByID(t.WorkingHourID), t, false);
            SaveChanges();
            return ReadByID(t.WorkingHourID);
        }

        public override BLL.Model.WorkingHour.WorkingHour Duplicate(BLL.Model.WorkingHour.WorkingHour t)
        {
            return Add(Create(t.StartTime, t.EndTime, t.CompanyProjectID));
        }

        protected override BLL.Model.WorkingHour.WorkingHour ReadByID(int id)
        {
            return DT.SingleOrDefault(x => x.WorkingHourID == id);
        }

        protected override void UpdateObject(BLL.Model.WorkingHour.WorkingHour left, BLL.Model.WorkingHour.WorkingHour right, bool replaceID)
        {
            if (replaceID) left.WorkingHourID = right.WorkingHourID;
            left.StartTime = right.StartTime;
            left.EndTime = right.EndTime;
            left.CompanyProjectID = right.CompanyProjectID;
            
        }

        protected override IEnumerable<BLL.Model.WorkingHour.WorkingHour> ApplyOrdering(IEnumerable<BLL.Model.WorkingHour.WorkingHour> query, IDictionary<Func<BLL.Model.WorkingHour.WorkingHour, object>, Enum.Ordering> columns)
        {
            return OrderHelper.ApplyOrdering<BLL.Model.WorkingHour.WorkingHour, object>(query, columns, workinghour => workinghour.WorkingHourID);
        }

        protected BLL.Model.WorkingHour.WorkingHour Create(DateTime start, DateTime end, int user)
        {
            return new BLL.Model.WorkingHour.WorkingHour()
            {
                StartTime = start,
                EndTime = end,
                CompanyProjectID = user
            };
        }

        internal IEnumerable<BLL.Model.WorkingHour.WorkingHour> ReadAllMyTotalWorkingHoursForProject(int companyProjectID)
        {
            return from wh in DT
                   where wh.CompanyProjectID == companyProjectID
                   select wh;
        }

        internal IEnumerable<BLL.Model.WorkingHour.WorkingHour> ReadTotalWorkingHoursForProject(int projectID)
        {
            return from wh in DT
                   where wh.CompanyProject.ProjectID == projectID
                   select wh;
        }

        internal IEnumerable<BLL.Model.WorkingHour.WorkingHour> ReadMyTotalChargedForProject(int companyProjectID)
        {
            return from wh in DT
                   where wh.CompanyProjectID == companyProjectID && wh.Charged == true
                   select wh;
        }

        internal IEnumerable<BLL.Model.WorkingHour.WorkingHour> ReadAllWorkingHoursFromUserProjectInPeriodAndSetCharged(int companyprojectid, DateTime van, DateTime tot)
        {
            var wh1 = from wh in DT
                      where wh.CompanyProjectID == companyprojectid && wh.StartTime >= van && wh.StartTime <= tot && wh.EndTime <= tot && wh.EndTime > van && wh.Charged == false
                      select wh;

            wh1.All(f => f.Charged == true);
            return wh1;
        }
        

        internal IEnumerable<BLL.Model.WorkingHour.WorkingHour> ReadAllWorkingHoursFromUserProjectInPeriodCharged(int companyprojectid, DateTime van, DateTime tot)
        {
            return from wh in DT
                   where wh.CompanyProjectID == companyprojectid && wh.StartTime >= van && wh.StartTime <= tot && wh.EndTime <= tot && wh.EndTime > van && wh.Charged == true
                   select wh;
        }
    }
}